import sounddevice as sd
import wave
import time
import numpy as np
import audioop
from scipy import fftpack
from untils.voiceMonitor import get_vocie_txt
from untils.tts import play
from query_processor import reply
from config import is_system_running  # 导入系统状态检查函数
from pydub import AudioSegment

APP_ID = '119880757'
API_KEY = '4ln36CeO6CSR1iQsPkOTMpUU'
SECRET_KEY = 'YM04MGWq1TsAlzx2z6Ri30Eba64InVnD'

class AudioMonitor:
    def __init__(self):
        # 音频参数配置
        self.CHUNK = 1024
        self.FORMAT = 'int16'  # sounddevice使用字符串格式
        self.CHANNELS = 1
        self.RATE = 16000
        self.OUTPUT_FILE = "audio\cache.wav"
        # 指定使用USB麦克风 - 需要根据sounddevice的设备ID进行调整
        # 可以通过运行 sd.query_devices() 查看可用设备
        self.DEVICE_INDEX = 1  # 可能需要根据sounddevice的设备ID调整

        # 能量检测参数 - 调整这些阈值
        self.VOICE_THRESHOLD = 3500    # 降低语音能量阈值
        self.SILENCE_THRESHOLD = 3000   # 降低静音能量阈值
        self.MAX_SILENCE_DURATION = 2.0 # 最大允许静音时长(秒)
        self.MIN_VOICE_DURATION = 0.3   # 最小语音持续时间(秒)

        self.frames = []

    def calculate_energy(self, audio_data):
        """计算音频帧的能量值 - 使用RMS方法更可靠"""
        # 将numpy数组转换为字节数据以使用audioop
        audio_bytes = audio_data.tobytes()
        return audioop.rms(audio_bytes, 2)  # 2表示16位采样

    def monitor(self):
        """监控麦克风并智能录音"""
        print("等待语音输入... (静音超过2秒自动停止)")

        recording = False
        silence_duration = 0
        voice_start = 0
        last_time = time.time()

        try:
            # 使用sounddevice的InputStream
            with sd.InputStream(device=self.DEVICE_INDEX,
                               channels=self.CHANNELS,
                               samplerate=self.RATE,
                               blocksize=self.CHUNK,
                               dtype=self.FORMAT) as stream:
                while True:
                    try:
                        # 读取音频数据
                        data, overflowed = stream.read(self.CHUNK)
                        energy = self.calculate_energy(data)
                        print(f"能量: {energy}")
                        
                        if energy > self.VOICE_THRESHOLD:
                            if not recording:
                                recording = True
                                voice_start = time.time()
                                print("检测到语音，开始录音...")
                            self.frames.append(data.tobytes())
                            silence_duration = 0
                        else:
                            if recording:
                                current_time = time.time()
                                silence_duration += current_time - last_time
                                self.frames.append(data.tobytes())

                                # 静音超时或录音超长停止
                                if silence_duration > self.MAX_SILENCE_DURATION:
                                    print(f"检测到静音，停止录音")
                                    break
                                if current_time - voice_start > 10:  # 最长录音10秒
                                    print("达到最大录音时长")
                                    break
                        
                        last_time = time.time()
                        
                    except Exception as e:
                        print(f"读取音频时发生错误: {e}")
                        continue
                        
        except KeyboardInterrupt:
            print("程序被用户中断")
        except Exception as e:
            print(f"打开音频流时发生错误: {e}")
        finally:
            self._save_recording()

    def _save_recording(self):
        """保存录音文件"""
        if len(self.frames) > 0:
            # 保存为 wav
            wf = wave.open(self.OUTPUT_FILE, 'wb')
            wf.setnchannels(self.CHANNELS)
            wf.setsampwidth(2)  # 16位采样宽度为2字节
            wf.setframerate(self.RATE)
            wf.writeframes(b''.join(self.frames))
            wf.close()
            print(f"录音已保存至 {self.OUTPUT_FILE}")
            


def Monitor():
    play("你有什么想说的吗？")
    while True:
        if not is_system_running():
            print("系统已停止，退出对话")
            break
        monitor = AudioMonitor()
        monitor.monitor()
        text_in = get_vocie_txt()
        print(text_in)
        if text_in =="":
            play("您说什么，没听清呢")
            continue
        text_out = reply(text_in)
        if "谢谢" in text_in:
            play(text_out)
            break
        else:
            play(text_out)